package net.lcheng.shop.Controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import net.lcheng.commons.utils.IPTools;
import net.lcheng.model.OOrder;
import net.lcheng.service.ShoppingService;
import net.lcheng.service.TradeManageService;
import net.lcheng.shop.utils.weixinpay.HttpRequest;
import net.lcheng.shop.utils.weixinpay.RandomStringGenerator;
import net.lcheng.shop.utils.weixinpay.SignUtil;
import net.lcheng.shop.utils.weixinpay.XMLParser;
import net.lcheng.shop.vo.CurrentUserModel;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

/**
 * 订单支付相关
 * Created by LV on 2016/7/27.
 */
@Controller
public class AjaxOrderPaymentController {

    private static final Logger log=Logger.getLogger(AjaxOrderPaymentController.class);

    private static String key="zrx2016zhaorenxue0501dianmo0112X";//生成签名的密码，在公众平台账号中设置的
    @Autowired
    private TradeManageService tradeManageService;
    @Autowired
    private ShoppingService shoppingService;
    /**
     * 订单支付
     * @param orderId 订单Id
     * @return String
     */
    @ResponseBody
    @RequestMapping(value = "/order/orderPay",method = RequestMethod.GET)
    public String orderPay(@RequestParam("oid") String orderId, HttpServletRequest request)throws Exception{
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser.isAuthenticated()) {
            Session session = currentUser.getSession();
            CurrentUserModel currentUserModel = JSONObject.parseObject(session.getAttribute("user").toString(), CurrentUserModel.class);
            //查询订单信息
            OOrder order=tradeManageService.getOrderByPrimaryKey(orderId);

            String userAgent=request.getHeader("User-Agent");

            if (order!=null) {
                /**微信支付请求参数*/
                Map<String, Object> requestParm = new TreeMap<>();
                requestParm.put("appid", "wx0071d459ab95ac0f");//公众账号ID
                requestParm.put("attach", orderId);//附加数据我们带订单ID,方便我们在微信支付回调后对数据库进行操作
                requestParm.put("body", "你的订单");//商品描述:根据需要填
                requestParm.put("mch_id", "1312419001");//商户号1312419001
                requestParm.put("nonce_str", RandomStringGenerator.getRandomStringByLength(32));//随机字符串
                requestParm.put("notify_url", "http://shop.lchina.cc/order/paymentSuccess");//接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数。
                requestParm.put("openid", currentUserModel.getOpenId());//trade_type=JSAPI，此参数必传，用户在商户appid下的唯一标识
                requestParm.put("out_trade_no", RandomStringGenerator.getRandomStringByLength(32));//out_trade_no商户订单号
                requestParm.put("spbill_create_ip", IPTools.getIpAddr(request));//APP和网页支付提交用户端ip
                requestParm.put("total_fee", String.valueOf((int)(order.getPaymentMoneyAmount().doubleValue() * 100)));//订单总金额，微信支付是1分钱为单位的，不能带小数点
                requestParm.put("trade_type", "JSAPI");//JSAPI--公众号支付
                String sign = SignUtil.getSign(requestParm, key);//生成签名
                requestParm.put("sign", sign);

                /**微信支付请求参数*/
                log.info("微信支付请求参数:" + requestParm.toString());

                //将需要发送给API的参数转换成规定的xml类型
                String requestXml = XMLParser.mapToXML(requestParm);
                /**请求参数转换成xml格式*/
                log.info("请求参数转换成xml格式:" + requestXml);

                /**调用微信请求的API*/

                String responseXml;
                try {
                    responseXml = HttpRequest.httpRequest("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXml,"1312419001");//证书密码默认是商户号
                    //返回的xml格式数据
                    log.info("返回的xml格式数据:" + responseXml);

                } catch (Exception e) {
                    return null;//如果请求失败，说明请求过程发生了错误，我们在返回的页面做处理
                }


                /**将返回的xml转换map格式*/
                Map<String, Object> responseMap = XMLParser.getMapFromXML(responseXml);
                /**返回数据转换成map格式*/
                log.info("返回数据转换成map格式:" + responseMap.toString());

                /**查看签名是否被修改*/
                if (SignUtil.checkIsSignValidFromResponseString(responseXml, key)) {
                    /**没有修改就做下一步判断*/
                    //result_code成功时才会返回prepay_id
                    if (responseMap.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
                        //添加发起时间

                        //给微信JSAPI准备发送数据
                        Map<String, Object> parameters = new TreeMap<>();
                        parameters.put("appId", "wx0071d459ab95ac0f");
                        parameters.put("timeStamp", Long.toString(new Date().getTime()));
                        parameters.put("nonceStr", RandomStringGenerator.getRandomStringByLength(32));
                        parameters.put("package", "prepay_id=" + responseMap.get("prepay_id").toString());
                        parameters.put("signType", "MD5");
                        String paySign = SignUtil.getSign(parameters, key);
                        parameters.put("paySign", paySign);//用签名算法算出来的
                        //当前微信浏览器的版本，5.0以上才支持微信支付
                        char agent = userAgent.charAt(userAgent.indexOf("MicroMessenger") + 15);
                        parameters.put("agent", new String(new char[]{agent}));
                        // parameters.put("agent","5.5");//测试时写死
                        parameters.put("sendUrl", "order/checkPaySuccess");//支付成功的回调地址----我们回调时可以查询一下数据库，是否支付成功，如果没有支付成功,返回到支付页面再支付---TODO

                        /**为支付JSAPI准备的数据*/
                        log.info("为支付JSAPI准备的数据:" + parameters.toString());

                        return JSON.toJSONString(parameters);

                    }
                    return "";
                }
                return "";
            }
            return "";
        }
        return "";//未登陆用户
    }

    /**
     * 微信支付完成后，通知的支付结果notify_url,由微信服务器请求的异步地址
     * @param request res
     * @param response resp
     */
    @ResponseBody
    @RequestMapping(value = "/order/paymentSuccess",method = RequestMethod.GET)
    public void paymentSuccess(HttpServletRequest request, HttpServletResponse response) throws Exception {
        InputStream inputStream = request.getInputStream();

        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        outStream.close();
        inputStream.close();

        String result = new String(outStream.toByteArray(), "utf-8");

        /**通知的支付结果notify_url返回的数据*/
        log.info("notify_url返回的数据:" + result);

        Map<String, Object> map = XMLParser.getMapFromXML(result);//返回数据转换成map

        log.info("notify_url返回的数据转换map格式:" + map.toString());


        if (map.get("result_code").toString().equalsIgnoreCase("SUCCESS")) {
            //对数据库进行操作
            //获取放入attach的订单Id
            String orderId = map.get("attach").toString();

            //修改数据库的几个支付状态
            OOrder order=tradeManageService.getOrderByPrimaryKey(orderId);
            order.setPaymentMethod(1);//微信支付（支付方式）
            order.setPaymentStatus(2);//支付成功（支付状态）
            order.setPaymentTime(new Date());//支付时间
            order.setOrderStatus(1);//订单状态（已支付）
            /**更新数据库*/
            shoppingService.paymentByBuyer(order);
        }
        //告诉微信服务器，支付完成
        response.getWriter().write(XMLParser.setXML("SUCCESS", "OK"));
    }


    /**
     * 在jsAPI中支付成功时我们验证一下是否支付成功（支付成功回调的函数在更改支付信息）
     * @return String
     */
    @RequestMapping(value = "/order/checkPaySuccess",method = RequestMethod.GET)
    public String checkPaySuccess(Model model, @RequestParam("oid") String orderId){
        Subject currentUser = SecurityUtils.getSubject();
        if (currentUser.isAuthenticated()) {
            //查询数据库信息
            OOrder order = tradeManageService.getOrderByPrimaryKey(orderId);
            //如果支付成功返回成功页面，如果支付失败，返回失败页面
            if (order != null) {
                if (order.getPaymentStatus()==2) {
                    model.addAttribute("order", order);
                    return "/user_order/payment_success";//跳转到支付成功的页面
                }else
                    return "";//todo 跳转到支付失败的页面
            }
            return "redirect:/error";
        }
        return "redirect:/login";
    }
}
